package com.un.web.common.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.un.core.common.R;
import com.un.web.common.domain.entity.SysFile;
import com.un.web.common.service.SysFileService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;

/**
 * @Author xingjian
 * @Date 2023-01-30
 **/
@RestController
@RequestMapping("/file")
public class FileController {

    @Value("${file.upload.path}")
    private String fileUploadPath;

    @Autowired
    private SysFileService sysFileService;


    @PostMapping("upload")
    public R uploadFile(MultipartFile file, HttpServletRequest request) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String formatDate = DateUtil.formatDate(new Date());
        String path=fileUploadPath+formatDate+"/";
        SysFile sysFile = new SysFile();
        sysFile.setOriginalName(originalFilename);
        sysFile.setUploadTime(new Date());
        sysFile.setPath(path);
        File tempFile = new File(path);
        if (!tempFile.exists()) {
            tempFile.mkdir();
        }
        String token = request.getHeader("token");
        if (!StrUtil.isBlankIfStr(token)){
            sysFile.setUserId(Integer.valueOf(JWT.decode(token).getAudience().get(0)));
        }
        String type = FileUtil.extName(originalFilename);
        String uuid = IdUtil.fastSimpleUUID();
        File uploadFile = new File(path + uuid + StrUtil.DOT + type);
        String md5 = SecureUtil.md5(file.getInputStream());
        SysFile fileByMd5 = getFileByMd5(md5);
        sysFile.setMd5(md5);
        if (!StrUtil.isBlankIfStr(fileByMd5)){
            sysFile.setUrl(fileByMd5.getUrl());
            sysFile.setName(fileByMd5.getName());
            sysFile.setType(fileByMd5.getType());
        }else {
            sysFile.setName(uuid);
            sysFile.setUrl(path+uuid+StrUtil.DOT+type);
            sysFile.setType(type);
            file.transferTo(uploadFile);
        }
        sysFileService.save(sysFile);
        return R.success();
    }

    @GetMapping("downFile/{name}")
    public  R downFile(@PathVariable String name,HttpServletResponse response){
        SysFile sysFile = sysFileService.getOne(new QueryWrapper<SysFile>().eq("name",name));
        File file = new File(sysFile.getUrl());
        if (ObjectUtils.isNotEmpty(file) && file.exists()) {
            java.io.OutputStream os = null;
            try {
                os = response.getOutputStream();
                response.reset();
                response.addHeader("Content-Disposition",
                        "attachment; filename=" + URLEncoder.encode(sysFile.getName()+StrUtil.DOT+sysFile.getType(), StandardCharsets.UTF_8));
                response.setContentType("application/force-download");
                os.write(FileUtil.readBytes(file));
                os.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else {
            try {
                response.sendError(404);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return R.success();
    }

    private SysFile getFileByMd5(String md5) {
        // 查询文件的md5是否存在
        QueryWrapper<SysFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5", md5);
        List<SysFile> filesList = sysFileService.list(queryWrapper);
        return filesList.size() == 0 ? null : filesList.get(0);
    }


}
